package com.yungu.swift.order.helper;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.assets.driver.model.dto.CarDto;
import com.yungu.swift.assets.driver.model.dto.DriverDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerEmergencyDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerEmergencyMemberDto;
import com.yungu.swift.assets.passenger.service.PassengerEmergencyMemberService;
import com.yungu.swift.assets.passenger.service.PassengerEmergencyService;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.lbs.model.DriverPoint;
import com.yungu.swift.lbs.model.vo.DrivingNearestVo;
import com.yungu.swift.lbs.service.DistanceService;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.order.model.dto.OrderDetailDto;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.vo.JsonOrderDetailVo;
import com.yungu.swift.order.utils.CommonUtils;
import com.yungu.swift.order.utils.SendMessageUtils;
import com.yungu.swift.socket.push.model.PushContent;
import com.yungu.swift.socket.push.service.PushService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author : cuixiuyin
 * @date : 2019/11/25
 */
@Slf4j
@Component
public class OrderPushHelper {

    private static PushService pushService;
    private static PassengerEmergencyService passengerEmergencyService;
    private static PassengerEmergencyMemberService passengerEmergencyMemberService;
    private static LocationService locationService;
    private static DistanceService distanceService;

    /**
     * 订单行程长链接推送消息 —— 推送乘客
     *
     * @param userUuid  用户uuid
     * @param orderUuid 订单uuid
     * @param appid     租户appid
     * @param msg       内容
     * @param title     标题
     * @param opCode    操作码
     * @return
     */
    public static void pushOrder2Pas(String userUuid, String orderUuid, String appid, String title, String msg,
                                     int opCode, Map<String, Object>... extraMap) {
        pushService.sendMessage(userUuid, PushContent.newInstance4Pas(appid, opCode, buildDataMap(orderUuid, title, msg, extraMap)));
    }

    /**
     * 订单行程长链接推送消息 —— 推送司机
     *
     * @param userUuid  用户uuid
     * @param orderUuid 订单uuid
     * @param appid     租户appid
     * @param msg       内容
     * @param title     标题
     * @param opCode    操作码
     * @return
     */
    public static void pushOrder2Dri(String userUuid, String orderUuid, String appid, String title, String msg,
                                     int opCode, Map<String, Object>... extraMap) {
        pushService.sendMessage(userUuid, PushContent.newInstance4Dri(appid, opCode, buildDataMap(orderUuid, title, msg, extraMap)));
    }


    /**
     * 订单行程长链接推送消息 —— 推送乘客
     *
     * @param userUuids 用户 uuid 集合
     * @param orderUuid 订单uuid
     * @param msg       内容
     * @param title     标题
     * @param opCode    操作码
     * @return
     */
    public static void pushListOrder2Pas(List<String> userUuids, String orderUuid, String appid, String title, String msg,
                                         int opCode, Map<String, Object>... extraMap) {
        pushService.sendMessageByList(userUuids, PushContent.newInstance4Pas(appid, opCode, buildDataMap(orderUuid, title, msg, extraMap)));
    }


    /**
     * 订单行程长链接推送消息 —— 推送司机
     *
     * @param userUuids 用户 uuid 集合
     * @param orderUuid 订单uuid
     * @param msg       内容
     * @param title     标题
     * @param opCode    操作码
     * @return
     */
    public static void pushListOrder2Dri(List<String> userUuids, String orderUuid, String appid, String title, String msg,
                                         int opCode, Map<String, Object>... extraMap) {
        pushService.sendMessageByList(userUuids, PushContent.newInstance4Dri(appid, opCode, buildDataMap(orderUuid, title, msg, extraMap)));
    }

    private static Map<String, Object> buildDataMap(String orderUuid, String title, String msg, Map<String, Object>... extraMap) {
        Map<String, Object> dataMap = MapUtils.build(8);
        dataMap.put("orderUuid", orderUuid);
        dataMap.put("title", title);
        dataMap.put("content", msg);
        dataMap.put("report", msg);
        if (extraMap.length > 0) {
            dataMap.putAll(extraMap[0]);
        }
        return dataMap;
    }


    /**
     * 预约单抢单推送内容
     */
    public static Map<String, Object> buildPushMap(OrderDto orderDto, OrderDetailDto orderDetailDto) {
        Map<String, Object> pushMap = new HashMap<>(8);
        // 拼接推送内容
        StringBuilder sBuilder = new StringBuilder();
        if (CommonConstant.TYPE_TIME_APPIONT == orderDto.getTypeTime()) {
            sBuilder.append("预约订单，").append(CommonUtils.getTimeTodayOrTomorrow(orderDetailDto.getDeparTime())).append("出发");
        } else if (CommonConstant.BUSINESS_TYPE_PARCEL == orderDto.getTypeModule()) {
            sBuilder.append("寄件，");
        } else {
            sBuilder.append("用车，");
        }
        sBuilder.append(CommonUtils.getTimeTodayOrTomorrow(orderDetailDto.getDeparTime()));
        sBuilder.append("从");
        sBuilder.append(orderDetailDto.getOriginAddress());
        sBuilder.append("到");
        if (CommonConstant.TYPE_TIME_REAL_TIME != orderDto.getTypeTime()) {
            sBuilder.append("，点击抢单");
        }
        pushMap.put("orderUuid", orderDetailDto.getOrderUuid());
        pushMap.put("title", "有新的订单");
        pushMap.put("content", sBuilder.toString());
        pushMap.put("typeModule", orderDto.getTypeModule());
        pushMap.put("report", sBuilder.toString());
        return pushMap;
    }

    /**
     * 实时单推单推送内容
     *
     * @param jsonOrderDetailVo
     * @return
     */
    public static String buildReportInfo(JsonOrderDetailVo jsonOrderDetailVo) {
        //播报内容
        StringBuilder report = new StringBuilder();
        if (CommonConstant.TYPE_TIME_REAL_TIME == jsonOrderDetailVo.getTypeTime()) {
            DriverPoint driverPoint = locationService.findDriverPoint(jsonOrderDetailVo.getActualDriverUuid(),
                    jsonOrderDetailVo.getAppid()).getData();
            if (driverPoint != null && driverPoint.getCoordinate() != null) {
                DrivingNearestVo drivingNearest = distanceService.getDrivingNearest(
                        jsonOrderDetailVo.getOriginLng(), jsonOrderDetailVo.getOriginLat(),
                        String.valueOf(driverPoint.getCoordinate().getLng()),
                        String.valueOf(driverPoint.getCoordinate().getLat())).getData();
                report.append("实时单,距您#");
                Double distance = drivingNearest.getDistance();
                if (distance > 1000) {
                    report.append(distance / 1000);
                    report.append("公里#,");
                } else {
                    report.append(distance);
                    report.append("米#,");
                }
            } else {
                report.append("实时单,");
            }
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_APPIONT) == 0) {
            report.append("预约单,");
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_SEND_AIRPORT) == 0) {
            report.append("送机,");
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_MEET_AIRPORT) == 0) {
            report.append("接机,");
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_DAILY_RENTAL) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_HALF_DAILY_RENTAL) == 0) {
            report.append(jsonOrderDetailVo.getTitle() + ",");
        }
        if (jsonOrderDetailVo.getTip() != null) {
            // 如果确定是整数，可以使用其他方式
            // 而且此方法固定了名称是"空驶费"，是否合适？别的订单类型？别的名称？
            String surcharge = jsonOrderDetailVo.getTip().toString();
            int surchargeInteger = Integer.parseInt(surcharge.replace(".00", "").replace(".0", ""));
            if (surchargeInteger > 0) {
                report.append("调度费").append(surchargeInteger).append("元,");
            }
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_APPIONT) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_SEND_AIRPORT) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_MEET_AIRPORT) == 0) {
            report.append(CommonUtils.getTimeTodayOrTomorrow(jsonOrderDetailVo.getDeparTime()));
        }
        report.append("从").append(CommonUtils.getCounty(jsonOrderDetailVo.getOriginDetailAddress())
                + jsonOrderDetailVo.getOriginAddress());
        //过滤包车目的地
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_DAILY_RENTAL) != 0 && jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_HALF_DAILY_RENTAL) != 0) {
            report.append("到").append(CommonUtils.getCounty(jsonOrderDetailVo.getDestDetailAddress()) + jsonOrderDetailVo.getDestAddress());
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_REAL_TIME) == 0) {
            if (jsonOrderDetailVo.getTypeTrip().compareTo(CommonConstant.BUSINESS_TYPE_TAXI) == 0) {
                report.append("的订单");
            } else {
                report.append("的订单，请尽快联系乘客,前往上车地点。您辛苦了，路上注意安全！");
            }
        }

        //预约单增加里程播报
        boolean falg = CommonConstant.BUSINESS_TYPE_TAXI != jsonOrderDetailVo.getTypeTrip()
                && CommonConstant.BUSINESS_TYPE_POOL != jsonOrderDetailVo.getTypeModule()
                && CommonConstant.BUSINESS_TYPE_PARCEL != jsonOrderDetailVo.getTypeModule()
                && (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_APPIONT) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_SEND_AIRPORT) == 0);
        if (falg) {
            report.append(",全程预计:").append(jsonOrderDetailVo.getPlanTrip()).append("公里");
        }
        if (StringUtils.isNotEmpty(jsonOrderDetailVo.getRemark())) {
            report.append(",").append(jsonOrderDetailVo.getRemark());
        }
        return report.toString();
    }

    /**
     * 乘客紧急联系人推送内容
     *
     * @param orderDto
     * @param orderDetailDto
     * @param driverDto
     * @param carDto
     */
    public static void passengerEmergencyPush(OrderDto orderDto, OrderDetailDto orderDetailDto, DriverDto driverDto, CarDto carDto) {
        //判断是否已经开启自动行程分享
        PassengerEmergencyDto emergencyDto = passengerEmergencyService.get(MapUtils.build(
                new String[]{"passengerUuid", "emergencyStatus"},
                new Object[]{orderDto.getPassengerUuid(), PassengerEmergencyDto.EMERGENCY_STATUS_VALID})).getData();
        //不为空说明开启了自动行程分享
        if (null != emergencyDto) {
            //判断生效时间段
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDate localDate = LocalDate.now();
            LocalDateTime startLocalDateTime = emergencyDto.getEmergencyTimeStart().toInstant().atZone(zoneId).toLocalTime().atDate(localDate);
            LocalDateTime endLocalDateTime = emergencyDto.getEmergencyTimeEnd().toInstant().atZone(zoneId).toLocalTime().atDate(localDate);
            LocalDateTime localDateTime = LocalDateTime.now();
            if (localDateTime.isBefore(startLocalDateTime) || localDateTime.isAfter(endLocalDateTime)) {
                log.info("passengerUuid 未发送信息给紧急联系人，时间区间不符合");
                return;
            }
            //推送乘客紧急联系人--预约单当司机去接乘客的时候才发短信
            List<PassengerEmergencyMemberDto> listMember = passengerEmergencyMemberService.list(MapUtils.build(
                    new String[]{"passengerUuid", "memberStatus"},
                    new Object[]{orderDto.getPassengerUuid(), PassengerEmergencyMemberDto.MEMBER_STATUS_VALID})).getData();
            if (CollectionUtils.isNotEmpty(listMember)) {
                SendMessageUtils.msgNoticeEmergencyMember(listMember, driverDto.getBusinessType(), orderDetailDto,
                        driverDto, carDto.getPlateNum());
            }
        }
    }


    @Reference
    public void setPushService(PushService pushService) {
        OrderPushHelper.pushService = pushService;
    }

    @Reference
    public void setPassengerEmergencyService(PassengerEmergencyService passengerEmergencyService) {
        OrderPushHelper.passengerEmergencyService = passengerEmergencyService;
    }

    @Reference
    public void setPassengerEmergencyMemberService(PassengerEmergencyMemberService passengerEmergencyMemberService) {
        OrderPushHelper.passengerEmergencyMemberService = passengerEmergencyMemberService;
    }

    @Reference
    public void setLocationService(LocationService locationService) {
        OrderPushHelper.locationService = locationService;
    }

    @Reference
    public void setDistanceService(DistanceService distanceService) {
        OrderPushHelper.distanceService = distanceService;
    }
}
